﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JSC.Portal.Services;
using System.Web.Mvc;
using JSC.Portal.Entities;
using NHibernate;
using JSC.Data.NHibernate;
using JSC.Portal.Web.Helper;
using JSC.Core;
using JSC.Core.Data;
using JSC.Portal.Web.HttpModules;
using System.Web;
using JSC.Core.Security.Cryptography;

namespace JSC.Portal.Web.Controllers
{
    [HandleError]
    public class PortalUsersController : ServicedController<IPortalUserService>
    {
        private IDao<Role> _roleDao;

        public PortalUsersController()
        {
            _roleDao = new CommonDao<Role>();
        }

        [Authorize(Roles = "Administrator,SiteAdministrator")]
        public ActionResult List()
        {
            PortalUser u = ControllerContext.CurrentUser();
            IList<PortalUser> users;
            if (User.IsInRole(Roles.Administrator.ToString()))
                users = Service.GetAll();
            else
                users = Service.GetSiteUsers(u.PortalSite.Url);

            return View(users);
        }

        [Authorize(Roles = "Administrator,SiteAdministrator")]
        public ActionResult Edit(int id)
        {
            IPortalSiteService siteSvc = FacadeFactory.CreateFacade<IPortalSiteService>();
            PortalUser user = Service.GetById(id, false);
            if (this.User.IsInRole(Roles.Administrator.ToString()))
                ViewData["PortalSites"] = new SelectList(siteSvc.GetAll(), "Id", "Name", user.PortalSite.Id);
            LoadSelectionLists(user);
            return View(user);
        }

        [Authorize(Roles = "Administrator,SiteAdministrator")]
        public ActionResult SaveOrUpdate(int id, string username, string password, string firstname, string lastname, 
            string email, bool isactive, int? portalsiteId, int[] selectedRoles)
        {
            string salt = Authentication.CreateSalt();
            string hashedPassword = Authentication.HashPassword(password, salt);
            
            using (ITransaction trans = NHibernateSession.Current.BeginTransaction())
            {
                PortalUser currentUser = ControllerContext.CurrentUser();
                IPortalSiteService siteSvc = FacadeFactory.CreateFacade<IPortalSiteService>();
                PortalUser user = Service.GetById(id, false, true);
                user.Username = username;
                user.Password = hashedPassword;
                user.PasswordSalt = salt;
                user.Firstname = firstname;
                user.Lastname = lastname;
                user.EMail = email;
                user.IsActive = isactive;
                user.PortalSite = portalsiteId.HasValue
                    ? siteSvc.GetById(portalsiteId.Value, false)
                    : currentUser.PortalSite;
                user.Roles.Clear();
                foreach (int rId in selectedRoles)
                {
                    Role r = _roleDao.GetById(rId, false);
                    user.Roles.Add(r);
                }

                user = Service.SaveOrUpdate(user);
                trans.Commit();
                return RedirectToAction("Edit", new { id = user.Id });
            }
        }

        [Authorize(Roles = "Administrator,SiteAdministrator")]
        public ActionResult Create(int id)
        {
            PortalUser user = new PortalUser();
            LoadSelectionLists(user);
            return View("Edit", user);
        }

        [Authorize(Roles = "Administrator,SiteAdministrator")]
        public ActionResult Delete(int id)
        {
            using (ITransaction trans = NHibernateSession.Current.BeginTransaction())
            {
                PortalUser user = Service.GetById(id, false);
                Service.Delete(user);
                trans.Commit();
                return RedirectToAction("List");
            }
        }

        public ActionResult Login()
        {
            this.ViewData["Languages"] = new SelectList(Language.GetLanguages(), "Culture", "Description", System.Threading.Thread.CurrentThread.CurrentUICulture);
            return PartialView("LoginControl");
        }

        public ActionResult LoginPage()
        {
            return View("Login");
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Login(string username, string password, bool rememberme, string language, string returnUrl)
        {
            string msg = string.Empty;
            string url = string.Empty;
            try
            {
                bool successfull = AuthenticationModule.AuthenticateUser(username, password, rememberme);
                if (successfull)
                {
                    HttpCookie c = new HttpCookie("JSC.Culture", language);
                    Response.Cookies.Add(c);
                    url = (!String.IsNullOrEmpty(returnUrl)) 
                        ? returnUrl 
                        : Url.Action("Index", ControllerNames.PORTALPAGES_CONTROLLER); 
                }
                else
                {
                    msg = Resources.Msg.UnknownUserOrPasswordIncorrect;
                }
            }
            catch(Exception ex)
            {
                msg = ex.Message;
            }
            return Json( new { RedirectUrl = url, ErrorMessage = msg } );
        }

        public ActionResult Logout()
        {
            AuthenticationModule.Logout();
            return RedirectToAction("ShowFriendlyUrl", ControllerNames.PORTALENGINE_CONTROLLER);
        }

        private void LoadSelectionLists(PortalUser portalUser)
        {
            IDictionary<Role, bool> roleDictionary = new Dictionary<Role, bool>();
            foreach (Role r in _roleDao.GetAll().OrderByDescending(r => r.Id))
            {
                if (r.RoleEnum == Roles.Administrator && !User.IsInRole(Roles.Administrator.ToString()))
                    continue;
                if (r.RoleEnum == Roles.Authenticated || r.RoleEnum == Roles.Anonymous)
                    continue;
                roleDictionary.Add(r, portalUser.IsInRole(r));
            }
            ViewData["Roles"] = roleDictionary;
        }
    }
}
